#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<cassert>
#include<sys/types.h>
void printbitmap(sigset_t pending)
{
    std::cout<<"pending bit map"<<std::endl;
    for(int signo = 31;signo > 0;signo--)
    {
        if(sigismember(&pending,signo))
        {
            std::cout<<"1";
        }
        else
        {
            std::cout<<"0";
        }
    }
        std::cout<<std::endl;
}
void handler(int signo)
{
    sigset_t pending;
    int n = sigpending(&pending);//将进程的位图写入pending中
    assert(n == 0);//是否获取成功
    //将位图打印出来
    std::cout<<"信号递达中..."<<std::endl;
    printbitmap(pending); 
    std::cout<<"自定义捕捉 "<<signo<<" 号信号,被递达"<<std::endl;
}
int main()
{
    //对2号信号进行自定义捕捉
    signal(2,handler);


    //1. 屏蔽2号信号--建立信号信号集，将信号集中2号位置写入1，并将信号集写入到进程pcb block信号集中
    sigset_t block,old_block;
    sigemptyset(&block);//初始未赋值，可能会是随机数，故需要清空。

    sigaddset(&block,2);//将2号信号，写入自己建立 block中
    //test:将所有信号都屏蔽
    // for(int signo = 1;signo <= 31;signo++)
    // sigaddset(&block,signo);//将2号信号，写入自己建立 block中
    // 将自己建立的信号集写入进程pcb中的信号集(写入内核中)
    int n = sigprocmask(SIG_SETMASK,&block,&old_block);//将信号集写入内核中，保存老的信号集，
    assert(n == 0);
    int cnt = 0;
    std::cout<<"block 2 signal success "<<std::endl;
    std::cout<<"process pid:"<<getpid()<<std::endl;
    while(true)
    {
        cnt++;
        //获得进程pending位图
        sigset_t pending;
        n = sigpending(&pending);//将进程的位图写入pending中
        assert(n == 0);//是否获取成功
        //将位图打印出来
        printbitmap(pending); 
        if(cnt == 20)
        {
            std::cout<<"解除对2号信号的屏蔽"<<std::endl;
            sigprocmask(SIG_UNBLOCK,&block,&old_block);//2号信号会被立即递达
        }
        //解除对2号信号的屏蔽
        sleep(1);
    }
    return 0;
}